package com.fly.openapi.controller;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import com.fly.core.entity.JsonResult;
import com.fly.core.utils.JsonBeanUtils;
import com.fly.openapi.entity.UserInfo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

@Slf4j
@Api(tags = "业务代码")
@RestController
@RequestMapping("/native")
public class NativeController
{
    @Autowired
    private WebClient webClient;
    
    Resource resource = new ClassPathResource("pic/001.jpg");
    
    @ApiOperation("关键字搜索")
    @PostMapping("/post")
    public String post(String keyword)
    {
        log.info("request keyword: {}", keyword);
        Mono<String> mono = webClient.post()
            .uri("http://124.71.129.204:8083/post")
            .contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .acceptCharset(StandardCharsets.UTF_8)
            .accept(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML)
            .body(BodyInserters.fromFormData("s", keyword))
            .retrieve() // 获取响应体
            .bodyToMono(String.class); // 响应数据类型转换
        return mono.block();
    }
    
    @ApiOperation("测试提交数据")
    @PostMapping("/test")
    public JsonResult<UserInfo> test(@Valid @RequestBody UserInfo userInfo)
    {
        return JsonResult.success(userInfo);
    }
    
    /**
     * 无返回值aop无法改变返回结果
     * 
     * @param response
     * @throws IOException
     */
    @ApiOperation("图片下载void")
    @GetMapping(value = "/pic/void", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE, MediaType.APPLICATION_JSON_VALUE})
    public void pic1(HttpServletResponse response)
        throws IOException
    {
        if (RandomUtils.nextBoolean())
        {
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setHeader("Content-Disposition", "attachment;filename=001.jpg");
            IOUtils.copy(resource.getInputStream(), response.getOutputStream());
            return;
        }
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setHeader("Content-Disposition", "attachment;filename=result.txt");
        response.getWriter().write(JsonBeanUtils.beanToJson(JsonResult.success()));
    }
    
    /**
     * aop改变返回结果
     * 
     * @param response
     * @throws IOException
     */
    @ApiOperation("图片下载byte[]")
    @GetMapping(value = "/pic/bytes", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE, MediaType.APPLICATION_JSON_VALUE})
    public byte[] pic2(HttpServletResponse response)
        throws IOException
    {
        if (RandomUtils.nextBoolean())
        {
            try (InputStream inputStream = resource.getInputStream())
            {
                response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
                response.setHeader("Content-Disposition", "attachment;filename=001.jpg");
                return IOUtils.toByteArray(inputStream);
            }
        }
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setHeader("Content-Disposition", "attachment;filename=result.txt");
        return JsonBeanUtils.beanToJson(JsonResult.success()).getBytes(StandardCharsets.UTF_8);
    }
    
    /**
     * aop里怎么新建StreamingResponseBody？答案：无需返回StreamingResponseBody，只需在response写入数据即可
     * 
     * @param response
     * @throws IOException
     */
    @ApiOperation("图片下载Stream")
    @GetMapping(value = "/pic/stream", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE, MediaType.APPLICATION_JSON_VALUE})
    public StreamingResponseBody pic3(HttpServletResponse response)
        throws IOException
    {
        return (output) -> {
            if (RandomUtils.nextBoolean())
            {
                try (InputStream input = resource.getInputStream())
                {
                    response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
                    response.setHeader("Content-Disposition", "attachment;filename=001.jpg");
                    output.write(IOUtils.toByteArray(input));
                }
            }
            else
            {
                response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
                response.setHeader("Content-Disposition", "attachment;filename=result.txt");
                output.write(JsonBeanUtils.beanToJson(JsonResult.success()).getBytes(StandardCharsets.UTF_8));
            }
        };
    }
}
